﻿// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using Phidgets;
using Phidgets.Events;

namespace Coding4Fun.BoxingBots.Robot
{
	public class RelayController : PhidgetInterfaceController
    {
		private const int TotalRelays = 4;
        private const int ThreadTick = 10;
        private readonly Dictionary<int, int> _timeDelays;
		
		internal RelayController(InterfaceKit phidgetInterfaceKit) : base(phidgetInterfaceKit)
		{
			_timeDelays = new Dictionary<int, int>();

			PhidgetInterfaceKit.OutputChange += _relayController_OutputChange;
		}

        void _relayController_OutputChange(object sender, OutputChangeEventArgs e)
        {
            // closed
            if (!e.Value)
                return;

            ThreadPool.QueueUserWorkItem(state =>
                                             {
                                                 if (_timeDelays.ContainsKey(e.Index))
                                                 {
                                                     while (_timeDelays[e.Index] > 0)
                                                     {
                                                         Thread.Sleep(ThreadTick);
                                                         _timeDelays[e.Index] -= ThreadTick;
                                                     }
                                                 }

                                                 Close(e.Index);
                                             });
        }

        public int GetTimeDelay(int index)
        {
            if (!_timeDelays.ContainsKey(index))
                return 0;

            return _timeDelays[index];
        }

        public void AlterTimeDelay(int index, int autoCloseDelay)
        {
            _timeDelays[index] = autoCloseDelay;
        }

        public void Open(int index, int autoCloseDelay)
        {
            UseRelay(index, true, autoCloseDelay);
        }

        public void Open(Collection<int> indexes, int autoCloseDelay)
        {
            if (indexes == null)
                return;

            foreach (var index in indexes)
                Open(index, autoCloseDelay);
        }

        public void Close(int index)
        {
            UseRelay(index, false, 0);
        }

        public void Close(Collection<int> indexes)
        {
            if (indexes == null)
                return;

            foreach (var index in indexes)
                Close(index);
        }

        private static bool IsValidIndex(int index)
        {
            return (index < TotalRelays || index >= 0);
        }

        private void UseRelay(int index, bool openRelay, int autoCloseDelay)
        {
            AlterTimeDelay(index, autoCloseDelay);
			PhidgetInterfaceKit.outputs[index] = openRelay;
        }
		
        public override void Dispose()
        {
			PhidgetInterfaceKit.OutputChange -= _relayController_OutputChange;

			base.Dispose();
        }
    }
}